//
// Created on 2025/11/16.
// Author 秦光磊.

#include "render/egl_core.h"
#include "constant/constant.h"
#include "drawbase/draw_base.h"
#include "gencoordinate/gen_coordinate.h"
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <charconv>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <hilog/log.h>
#include <string>
constexpr int32_t NUM_4 = 4;
/**
 * 定点着色器
 */
// const char VERTEX_SHADER[] = "#version 300 es                                       \n"
//                              "layout(location = 0) in vec4 a_position;              \n"
//                              "layout(location = 1) in vec4 a_color;                 \n"
//                              "out vec4 v_color;                                     \n"
//                              "void main()                                           \n"
//                              "{                                                     \n"
//                              "gl_Position = a_position;        \n"
//                              "v_color = a_color;                                    \n"
//                              "}                                                     \n";
const char VERTEX_SHADER[] = "#version 300 es                                       \n"
                             "layout(location = 0) in vec4 a_position;              \n"
                             "layout(location = 1) in vec4 a_color;                 \n"
                             "uniform mat4 u_projectionMatrix;                      \n"
                             "out vec4 v_color;                                     \n"
                             "void main()                                           \n"
                             "{                                                     \n"
                             "gl_Position = u_projectionMatrix * a_position;        \n"
                             "v_color = a_color;                                    \n"
                             "}                                                     \n";
const char FRAGMENT_SHADER[] = "#version 300 es                                     \n"
                               "precision mediump float;                            \n"
                               "in vec4 v_color;                                    \n"
                               "out vec4 fragColor;                                 \n"
                               "void main()                                         \n"
                               "{                                                   \n"
                               "fragColor = v_color;                                \n"
                               "}                                                   \n";

/**
 * Draw color #7E8FFB.
 */
const GLfloat DRAW_COLOR[] = {126.0f / 255, 143.0f / 255, 251.0f / 255, 1.0f};

/**
 * Change color #92D6CC.
 */
const GLfloat CHANGE_COLOR[] = {146.0f / 255, 214.0f / 255, 204.0f / 255, 1.0f};

/**
 * EGL配置属性列表，用于指定EGL显示配置的参数要求,本应用，这些值固定不变。
 * EGL_SURFACE_TYPE, EGL_WINDOW_BIT：指定surface类型为窗口surface，用于在原生窗口上显示渲染内容；
 * EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE,8：设置颜色缓冲区的RGBA各分量位深为8位，
 * 即32位色深；
 * EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT：指定可渲染的API类型为OpenGL ES 2.0.
 */
const EGLint ATTRIB_LIST[] = {
    EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,     EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE};

/**
 * 这个属性数组通常作为eglCreateContext函数的参数，用于创建指定版本的OpenGL ES上下文环境.
 * EGL_CONTEXT_CLIENT_VERSION 属性指定要创建的OpenGL ES版本，此处设置为2表示需要OpenGL ES 2.0上下文.
 * 数字2对应EGL_CONTEXT_CLIENT_VERSION的值，明确要求使用OpenGL ES 2.0 API.
 * EGL_NONE 作为数组结束标记，表示属性列表的终止.
 */
const EGLint CONTEXT_ATTRIBS[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
/**
 * Program error.
 */
const GLuint PROGRAM_ERROR = 0;

/**
 * Position handle name.
 */
const char POSITION_NAME[] = "a_position";
/**
 * Position error.
 */
const GLint POSITION_ERROR = -1;
GLfloat BACKGROUND_COLOR[4] = {0.0f, 0.0f, 0.0f, 1.0f};
/**
 * Default x position.
 */
const int DEFAULT_X_POSITION = 0;

/**
 * Default y position.
 */
const int DEFAULT_Y_POSITION = 0;

/**
 * Gl red default.
 */
const GLfloat GL_RED_DEFAULT = 1.0;

/**
 * Gl green default.
 */
const GLfloat GL_GREEN_DEFAULT = 0.0;

/**
 * Gl blue default.
 */
const GLfloat GL_BLUE_DEFAULT = 0.0;

/**
 * Gl alpha default.
 */
const GLfloat GL_ALPHA_DEFAULT = 1.0;

/**
 * Shape vertices size.
 */
const int SHAPE_VERTICES_SIZE = 8;

/**
 * Pointer size.
 */
const GLint POINTER_SIZE = 2;

/**
 * Triangle fan size.
 */
const GLsizei TRIANGLE_FAN_SIZE = 4;

/**
 * Background area.
 */
const GLfloat BACKGROUND_RECTANGLE_VERTICES[] = {-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f};

/**
 * Fifty percent.
 */
const float FIFTY_PERCENT = 0.5;

/**
 * EGL初始化过程，该过程就原子化了，后续不再拆解更新。再每帧上，该步骤执行一次。
 * 主要分两步进行：
 * 第一步：将已经创建好的native窗口，绑定到当前显示器上，后续会通过渲染表面渲染的图像都会显示到这个显示器上
 * 第二步：绑定着色器程序。
 * @param window XComponent窗口
 * @return 成功即可执行后续的渲染操作，否则需要排查原因
 */
bool EGLCore::EglContextInit(void *window) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s start.", __func__);
    eglWindow_ = static_cast<EGLNativeWindowType>(window);
    // 获取一个显示设备的连接，从而可以在该显示设备上进行图形渲染操作，使用默认显示设备
    eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (eglDisplay_ == EGL_NO_DISPLAY) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "eglGetDisplay:unable to get display.errcode:%{public}d", eglGetError());
        return false;
    }


    // 验证上一步获取的显示连接的有效性，并准备EGL内部资源以供后续操作使用。同时并查询EGL实现的版本号。
    EGLint majorVersion;
    EGLint minorVersion;
    if (!eglInitialize(eglDisplay_, &majorVersion, &minorVersion)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "eglInitialize:unable to get initialize EGL display.errcode:%{public}d", eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore",
                 "eglInitialize::majorVersion：%{public}d minorVersion：%{public}d", majorVersion, minorVersion);

    // ELG配置选择,属性为ATTRIB_LIST，返回一个可用的配置即可
    const EGLint maxConfigSize = 1;
    EGLint numConfigs;
    if (!eglChooseConfig(eglDisplay_, ATTRIB_LIST, &eglConfig_, maxConfigSize, &numConfigs)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "eglChooseConfig:unable to choose config.errcode:%{public}d", eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "eglChooseConfig。实际匹配的数量：%{public}d.",
                 numConfigs);

    // 创建渲染表面
    if (eglWindow_ == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglWindow_ is null.errcode:%{public}d",
                     eglGetError());
    }
    eglSurface_ = eglCreateWindowSurface(eglDisplay_, eglConfig_, eglWindow_, NULL);
    if (eglSurface_ == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "eglCreateWindowSurface: unable to create surface.errcode:%{public}d", eglGetError());
        return false;
    }
    // 创建渲染上下文
    eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, EGL_NO_CONTEXT, CONTEXT_ATTRIBS);
    if (eglContext_ == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "eglCreateContext: fail to create context.errcode:%{public}d", eglGetError());
    }
    // 将EGL渲染表面与图形渲染上下文绑定到当前显示屏，以后在渲染表面上渲染的内容就可以显示在当前的显示器上
    if (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "eglMakeCurrent: fail to make current.errcode:%{public}d", eglGetError());
        return false;
    }
    // 截止到此，完成EGL的显示器的的创建，后续关联着色器

    // 加载顶点着色器
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "EglContextInit开始加载顶点着色器。");
    GLuint vertex = LoaderShader(GL_VERTEX_SHADER, VERTEX_SHADER);
    if (vertex == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "EglContextInit加载顶点着色器失败.errcode:%{public}d", eglGetError());
        return false;
    }

    // 加载片段着色器
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "EglContextInit开始加载片段着色器。");
    GLuint fragment = LoaderShader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
    if (fragment == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "EglContextInit加载片段着色器失败.errcode:%{public}d", eglGetError());
        return false;
    }

    // 创建一个空的着色器程序对象，将作为容器，将编译好的顶点着色器和片段着色器附加并链接起来，最终形成一个完整的可执行着色器程序
    program_ = glCreateProgram();
    if (program_ == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "createProgram program error.errcode:%{public}d",
                     eglGetError());
        glDeleteShader(vertex);
        glDeleteShader(fragment);
        return false;
    }
    // 将编译好的着色器对象，包括顶点着色器与片段着色器附加着色器程序
    glAttachShader(program_, vertex);
    glAttachShader(program_, fragment);
    // 将附加的着色器链接为可执行的完整程序
    glLinkProgram(program_);
    // 判断链接是否成功
    GLint success;
    glGetProgramiv(program_, GL_LINK_STATUS, &success);
    if (success == GL_FALSE) {
        // 链接失败，获取日志长度
        GLint logLength;
        glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &logLength);
        // 分配缓冲区并获取日志内容
        char *log = (char *)malloc(logLength);
        glGetProgramInfoLog(program_, logLength, NULL, log);
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "glLinkProgram链接失败.msg:%{public}s", log);
        glDeleteShader(vertex);
        glDeleteShader(fragment);
        free(log);
        return false;
    } else {
        // 链接成功，可以使用程序
        glUseProgram(program_);
        GLenum error = glGetError();
        if (error != GL_NO_ERROR) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "glUseProgram失败.code:%{public}d", error);
            return false;
        }
    }
    // 截至初始化完成
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "EglContextInit end.success.");
    return true;
}
/**
 * 搭建渲染入口。根据提供的nativeWindow建立渲染入口，后续渲染结果都关联到该nativeWindow.
 * @param nativeWindow 提供的OHNativeWindow
 * @return true-成功 false=失败
 */
bool EGLCore::BuildRenderEntrance(void *nativeWindow, EGLDisplay *eglDisplay, EGLSurface *eglSurface) {
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s start.", __func__);
    EGLNativeWindowType eglWindow = static_cast<EGLNativeWindowType>(nativeWindow);
    // 获取一个显示设备的连接，从而可以在该显示设备上进行图形渲染操作，使用默认显示设备
    *eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (*eglDisplay == EGL_NO_DISPLAY) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglGetDisplay:unable to get display.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    // 验证上一步获取的显示连接的有效性，并准备EGL内部资源以供后续操作使用。同时并查询EGL实现的版本号。
    EGLint majorVersion;
    EGLint minorVersion;
    if (!eglInitialize(*eglDisplay, &majorVersion, &minorVersion)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglInitialize:unable to get initialize EGL display.errcode:%{public}d", __func__,
                     eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore",
                 "%{public}s,eglInitialize::majorVersion：%{public}d minorVersion：%{public}d", __func__, majorVersion,
                 minorVersion);

    // ELG配置选择,属性为ATTRIB_LIST，返回一个可用的配置即可
    const EGLint maxConfigSize = 1;
    EGLint numConfigs;
    EGLConfig eglConfig = EGL_NO_CONFIG_KHR;
    if (!eglChooseConfig(*eglDisplay, ATTRIB_LIST, &eglConfig, maxConfigSize, &numConfigs)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglChooseConfig:unable to choose config.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore",
                 "%{public}s,eglChooseConfig。实际匹配的数量：%{public}d.", __func__, numConfigs);

    // 创建渲染表面
    if (eglWindow == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglWindow_ is null.errcode:%{public}d", __func__, eglGetError());
    }
    *eglSurface = eglCreateWindowSurface(*eglDisplay, eglConfig, eglWindow, NULL);
    if (*eglSurface == EGL_NO_SURFACE) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglCreateWindowSurface: unable to create surface.errcode:%{public}d", __func__,
                     eglGetError());
        return false;
    }
    // 创建渲染上下文
    EGLContext eglContext = eglCreateContext(*eglDisplay, eglConfig, EGL_NO_CONTEXT, CONTEXT_ATTRIBS);
    if (eglContext == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglCreateContext: fail to create context.errcode:%{public}d", __func__, eglGetError());
    }
    // 将EGL渲染表面与图形渲染上下文绑定到当前显示屏，以后在渲染表面上渲染的内容就可以显示在当前的显示器上
    if (!eglMakeCurrent(*eglDisplay, *eglSurface, *eglSurface, eglContext)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglMakeCurrent: fail to make current.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    return true;
}

/**
 * 建立渲染需要的着色器程序
 * @return true-成功 false=失败
 */
bool EGLCore::BuildShaderProgram(GLuint *program, int width, int height) {
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s start.", __func__);
    // 加载顶点着色器
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,LoaderShader开始加载顶点着色器。",
                 __func__);
    GLuint vertex = LoaderShader(GL_VERTEX_SHADER, VERTEX_SHADER);
    if (vertex == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,LoaderShader加载顶点着色器失败.errcode:%{public}d", __func__, eglGetError());
        return false;
    }

    // 加载片段着色器
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,LoaderShader开始加载片段着色器。",
                 __func__);
    GLuint fragment = LoaderShader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
    if (fragment == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,LoaderShader加载片段着色器失败.errcode:%{public}d", __func__, eglGetError());
        return false;
    }

    // 创建一个空的着色器程序对象，将作为容器，将编译好的顶点着色器和片段着色器附加并链接起来，最终形成一个完整的可执行着色器程序
    *program = glCreateProgram();
    if (*program == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,createProgram program error.errcode:%{public}d", __func__, eglGetError());
        glDeleteShader(vertex);
        glDeleteShader(fragment);
        return false;
    }
    // 将编译好的着色器对象，包括顶点着色器与片段着色器附加着色器程序
    glAttachShader(*program, vertex);
    glAttachShader(*program, fragment);
    // 将附加的着色器链接为可执行的完整程序
    glLinkProgram(*program);
    // 判断链接是否成功
    GLint success;
    glGetProgramiv(*program, GL_LINK_STATUS, &success);
    if (success == GL_FALSE) {
        // 链接失败，获取日志长度
        GLint logLength;
        glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &logLength);
        // 分配缓冲区并获取日志内容
        char *log = (char *)malloc(logLength);
        glGetProgramInfoLog(*program, logLength, NULL, log);
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,glLinkProgram链接失败.msg:%{public}s",
                     __func__, log);
        glDeleteShader(vertex);
        glDeleteShader(fragment);
        free(log);
        return false;
    } else {
        // 链接成功，可以使用程序
        glUseProgram(*program);
        GLenum error = glGetError();
        if (error != GL_NO_ERROR) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,glUseProgram失败.code:%{public}d",
                         __func__, error);
            return false;
        }
    }
    return true;
}

/**
 * 绘制帧前最后一波操作，准备视图窗口
 * @param width 视图宽度
 * @param height 视图高度
 * @param backgroundColor 背景颜色
 * @param backgroundSize 背景颜色数字数，一般是4
 * @return true-成功 false=失败
 */
bool EGLCore::BuildViewport(GLuint *program, float *drawWidth, float *drawHeight, float *screenRatio, int width,
                            int height, GLfloat backgroundColor[4], int backgroundSize) {
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s start.", __func__);
    if (backgroundSize < 4) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,param error.颜色大小错误:%{public}d",
                     __func__, backgroundSize);
        return false;
    }
    glViewport(0, 0, width, height);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,glViewport error.errcode:%{public}d",
                     __func__, eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore",
                 "%{public}s,glViewport success.x:0,y:0,width:%{public}d,height:%{public}d", __func__, width, height);

    glClearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], backgroundColor[3]);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glClearColor error.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    glClear(GL_COLOR_BUFFER_BIT);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,glClear error.errcode:%{public}d",
                     __func__, eglGetError());
        return false;
    }
    // 计算视图的宽高比
    *screenRatio = (float)width / (float)height;
    float left, right, bottom, top;
    float near = -1.0f, far = 1.0f;
    if (*screenRatio > 1.0f) {
        // 宽屏，调整宽度范围
        left = -*screenRatio;
        right = *screenRatio;
        bottom = -1.0f;
        top = 1.0f;
        // 此时绘制区域更新
        *drawWidth = *screenRatio * 2.0f;
        *drawHeight = 2.0f;
    } else {
        // 竖屏或正方形，调整高度范围
        left = -1.0f;
        right = 1.0f;
        bottom = -1.0f / *screenRatio;
        top = 1.0f / *screenRatio;
        // 此时绘制区域更新
        *drawWidth = 2;
        *drawHeight = 2.0f / *screenRatio;
    }
    float orthoMatrix[16] = {2.0f / (right - left),
                             0.0f,
                             0.0f,
                             -(right + left) / (right - left),
                             0.0f,
                             2.0f / (top - bottom),
                             0.0f,
                             -(top + bottom) / (top - bottom),
                             0.0f,
                             0.0f,
                             -2.0f / (far - near),
                             -(far + near) / (far - near),
                             0.0f,
                             0.0f,
                             0.0f,
                             1.0f};
    GLint uProjectionMatrix = glGetUniformLocation(*program, "u_projectionMatrix");
    if (uProjectionMatrix != -1) {
        glUniformMatrix4fv(uProjectionMatrix, 1, GL_FALSE, orthoMatrix);
    } else {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glUniformMatrix4fv失败.code:%{public}d", __func__, glGetError());
        return false;
    }
    return true;
}
bool EGLCore::EglContextInit2(void *window, int width, int height) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s start.", __func__);
    EGLNativeWindowType eglWindow = static_cast<EGLNativeWindowType>(window);
    // 获取一个显示设备的连接，从而可以在该显示设备上进行图形渲染操作，使用默认显示设备
    EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (eglDisplay == EGL_NO_DISPLAY) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglGetDisplay:unable to get display.errcode:%{public}d", __func__, eglGetError());
        return false;
    }

    // 验证上一步获取的显示连接的有效性，并准备EGL内部资源以供后续操作使用。同时并查询EGL实现的版本号。
    EGLint majorVersion;
    EGLint minorVersion;
    if (!eglInitialize(eglDisplay, &majorVersion, &minorVersion)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglInitialize:unable to get initialize EGL display.errcode:%{public}d", __func__,
                     eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore",
                 "%{public}s,eglInitialize::majorVersion：%{public}d minorVersion：%{public}d", __func__, majorVersion,
                 minorVersion);

    // ELG配置选择,属性为ATTRIB_LIST，返回一个可用的配置即可
    const EGLint maxConfigSize = 1;
    EGLint numConfigs;
    EGLConfig eglConfig = EGL_NO_CONFIG_KHR;
    if (!eglChooseConfig(eglDisplay, ATTRIB_LIST, &eglConfig, maxConfigSize, &numConfigs)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglChooseConfig:unable to choose config.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore",
                 "%{public}s,eglChooseConfig。实际匹配的数量：%{public}d.", __func__, numConfigs);

    // 创建渲染表面
    if (eglWindow == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglWindow_ is null.errcode:%{public}d", __func__, eglGetError());
    }
    EGLSurface eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglWindow, NULL);
    if (eglSurface == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglCreateWindowSurface: unable to create surface.errcode:%{public}d", __func__,
                     eglGetError());
        return false;
    }
    // 创建渲染上下文
    EGLContext eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, CONTEXT_ATTRIBS);
    if (eglContext == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglCreateContext: fail to create context.errcode:%{public}d", __func__, eglGetError());
    }
    // 将EGL渲染表面与图形渲染上下文绑定到当前显示屏，以后在渲染表面上渲染的内容就可以显示在当前的显示器上
    if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,eglMakeCurrent: fail to make current.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    // 截止到此，完成EGL的显示器的的创建，后续关联着色器

    // 加载顶点着色器
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,LoaderShader开始加载顶点着色器。",
                 __func__);
    GLuint vertex = LoaderShader(GL_VERTEX_SHADER, VERTEX_SHADER);
    if (vertex == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,LoaderShader加载顶点着色器失败.errcode:%{public}d", __func__, eglGetError());
        return false;
    }

    // 加载片段着色器
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,LoaderShader开始加载片段着色器。",
                 __func__);
    GLuint fragment = LoaderShader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
    if (fragment == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,LoaderShader加载片段着色器失败.errcode:%{public}d", __func__, eglGetError());
        return false;
    }

    // 创建一个空的着色器程序对象，将作为容器，将编译好的顶点着色器和片段着色器附加并链接起来，最终形成一个完整的可执行着色器程序
    GLuint program = glCreateProgram();
    if (program == PROGRAM_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,createProgram program error.errcode:%{public}d", __func__, eglGetError());
        glDeleteShader(vertex);
        glDeleteShader(fragment);
        return false;
    }
    // 将编译好的着色器对象，包括顶点着色器与片段着色器附加着色器程序
    glAttachShader(program, vertex);
    glAttachShader(program, fragment);
    // 将附加的着色器链接为可执行的完整程序
    glLinkProgram(program);
    // 判断链接是否成功
    GLint success;
    glGetProgramiv(program, GL_LINK_STATUS, &success);
    if (success == GL_FALSE) {
        // 链接失败，获取日志长度
        GLint logLength;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
        // 分配缓冲区并获取日志内容
        char *log = (char *)malloc(logLength);
        glGetProgramInfoLog(program, logLength, NULL, log);
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,glLinkProgram链接失败.msg:%{public}s",
                     __func__, log);
        glDeleteShader(vertex);
        glDeleteShader(fragment);
        free(log);
        return false;
    } else {
        // 链接成功，可以使用程序
        glUseProgram(program);
        GLenum error = glGetError();
        if (error != GL_NO_ERROR) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,glUseProgram失败.code:%{public}d",
                         __func__, error);
            return false;
        }
    }
    // 截至初始化完成


    // GLint position = PrepareDraw();
    glViewport(DEFAULT_X_POSITION, DEFAULT_Y_POSITION, width, height);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s,glViewport error.errcode:%{public}d",
                     __func__, eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore",
                 "%{public}s,glViewport success.x:%{public}d,y:%{public}d,width:%{public}d,height:%{public}d", __func__,
                 DEFAULT_X_POSITION, DEFAULT_Y_POSITION, width, height);
// 正交投影矩阵
    float screenRatio = (float)width / height;
    float left, right, bottom, top;
    float near = -1.0f, far = 1.0f;
    if (screenRatio > 1.0f) {
        // 宽屏，调整宽度范围
        left = -screenRatio;
        right = screenRatio;
        bottom = -1.0f;
        top = 1.0f;
    } else {
        // 竖屏或正方形，调整高度范围
        left = -1.0f;
        right = 1.0f;
        bottom = -1.0f / screenRatio;
        top = 1.0f / screenRatio;
    }
    float orthoMatrix[16] = {2.0f / (right - left),
                             0.0f,
                             0.0f,
                             -(right + left) / (right - left),
                             0.0f,
                             2.0f / (top - bottom),
                             0.0f,
                             -(top + bottom) / (top - bottom),
                             0.0f,
                             0.0f,
                             -2.0f / (far - near),
                             -(far + near) / (far - near),
                             0.0f,
                             0.0f,
                             0.0f,
                             1.0f};
    GLint uProjectionMatrix = glGetUniformLocation(program, "u_projectionMatrix");
    if (uProjectionMatrix != -1) {
        glUniformMatrix4fv(uProjectionMatrix, 1, GL_FALSE, orthoMatrix);
    } else {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glUniformMatrix4fv失败.code:%{public}d", __func__, glGetError());
        return false;
    }


    glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glClearColor error.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    glClear(GL_COLOR_BUFFER_BIT);


    std::vector<GLfloat> fromVertex = {0.0f, 0.0f, 0.0f};
    std::vector<GLfloat> toVertex = {0.1f, 0.9f, 0.9f};
    float centerVertex[] = {-0.5f, 0.0f, 0.0f};
    float color[] = {1.0f, 0.0f, 0.0f, 1.0f};
    int attr[] = {2, 2};
//    std::vector<GLfloat> ellipseCoordinates =
//        GenCoordinate::GenDottedStraightLineCoordinate(fromVertex, 3, toVertex, 3, attr, 2);
    std::vector<GLfloat> ellipseCoordinates =
        GenCoordinate::GenOneEllipseArcCoordinates(1, 2, fromVertex, 3, 7, 2, attr, 2);


//    std::vector<GLfloat> ellipseCoordinates;
//    ellipseCoordinates.push_back(0.0f);
//    ellipseCoordinates.push_back(0.0f);
//    ellipseCoordinates.push_back(0.0f);
//
//    ellipseCoordinates.push_back(0.0f);
//    ellipseCoordinates.push_back(0.35f);
//    ellipseCoordinates.push_back(0.00f);
//
//    ellipseCoordinates.push_back(0.30f);
//    ellipseCoordinates.push_back(0.00f);
//    ellipseCoordinates.push_back(0.00f);
//
//    ellipseCoordinates.push_back(1.11f);
//    ellipseCoordinates.push_back(1.23f);
//    ellipseCoordinates.push_back(1.31f);
//
//    ellipseCoordinates.push_back(1.42f);
//    ellipseCoordinates.push_back(1.58f);
//    ellipseCoordinates.push_back(0);
    int itemp = 0;
    for (GLfloat temp : ellipseCoordinates) {
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,111111第%{public}d个元素的值为%{public}f", __func__, itemp, temp);
        itemp++;
    }
    GLuint VAO, VBO;
    // 生成VAO
    glGenVertexArrays(1, &VAO);
    // 生成VBO
    glGenBuffers(1, &VBO);
    // 绑定VAO
    glBindVertexArray(VAO);
    // 绑定VBO到GL_ARRAY_BUFFER目标
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    // 将顶点数据传输到VBO
    glBufferData(GL_ARRAY_BUFFER, ellipseCoordinates.size() * sizeof(GLfloat), // 数据总字节数
                 ellipseCoordinates.data(),                                    // 数据指针
                 GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
    glEnableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glVertexAttrib4fv(1, color);

    glDrawArrays(GL_LINE_STRIP, 0, ellipseCoordinates.size() / 3);


    int i = 0;
    for (GLfloat item : ellipseCoordinates) {
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s 测试坐标，第%{public}d个坐标值：%{public}f.", __func__, i, item);
        i++;
    }

//    glDisableVertexAttribArray(0);
//    glDisableVertexAttribArray(1);
//    glFlush();
//    glFinish();
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s end.", __func__);
    return eglSwapBuffers(eglDisplay, eglSurface);
}

/**
 * 绘制最底层核心操作，给定一系列坐标，颜色，几何参数
 * @param shapeVertices 绘制的坐标系列
 * @param vertSize 坐标系列的数字数量
 * @param drawColor 绘制颜色
 * @param colorSize 颜色长度，一般是4
 * @param geometryAttribute 几何参数
 * 第1个，geometryAttribute[0]代表绘制线条的方式：虚线条-1，实线首位相连-2，实线条-3，三角形-4，三角形带-5，扇区-6，点-其它值
 * 第2个，geometryAttribute[1]代表绘制的图大小：1代表小图，采集点数少；2代表大图，采集点数多。采集的点能少就少，提高性能
 * @param attrSize 几何单数大小至少2个
 * @return false-失败 true-成功
 */
bool EGLCore::DrawAnyObject(std::vector<GLfloat> &shapeVertices, int vertSize, GLfloat drawColor[4], int colorSize,
                            int *geometryAttribute, int attrSize) {
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s start.", __func__);
    if ((vertSize < 3) || (colorSize < 4) || (attrSize < 2)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s param size err.vertSize:%{public}d,colorSize:%{public}d,attrSize:%{public}d", __func__,
                     vertSize, colorSize, attrSize);
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s 顶点坐标长度：%{public}d.", __func__,
                 vertSize);
    if (shapeVertices.size() < vertSize) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s startVector大小不对。shapeVertices.size():%zu.", __func__, shapeVertices.size());
        return false;
    }
    if (geometryAttribute == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s geometryAttribute为nullptr.",
                     __func__);
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s shapeVertices内容：.", __func__);
    int i = 0;
    for (GLfloat tempItem : shapeVertices) {
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s 第%{public}d个元素值为%f：.",
                     __func__, i, tempItem);
        i++;
    }
    GLuint VAO, VBO;
    // 生成VAO
    glGenVertexArrays(1, &VAO);
    // 生成VBO
    glGenBuffers(1, &VBO);
    // 绑定VAO
    glBindVertexArray(VAO);
    // 绑定VBO到GL_ARRAY_BUFFER目标
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    // 将顶点数据传输到VBO
    glBufferData(GL_ARRAY_BUFFER, shapeVertices.size() * sizeof(GLfloat), // 数据总字节数
                 shapeVertices.data(),                                    // 数据指针
                 GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glVertexAttribPointer error.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    glEnableVertexAttribArray(0);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glEnableVertexAttribArray error.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    // 因为要使用统一颜色，所以要先关闭顶点颜色位置
    glDisableVertexAttribArray(1);
    glVertexAttrib4fv(1, drawColor);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glVertexAttrib4fv error.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s geometryAttribute[0]:%{public}d.",
                 __func__, geometryAttribute[0]);
    switch (geometryAttribute[0]) {
    case 1:
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s glDrawArrays绘制虚线.", __func__);
        glDrawArrays(GL_LINES, 0, vertSize / 3);
        break;
    case 2:
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s glDrawArrays首尾相连.", __func__);
        glDrawArrays(GL_LINE_LOOP, 0, vertSize / 3);
        break;
    case 3:
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s glDrawArrays绘制实线.", __func__);
        glDrawArrays(GL_LINE_STRIP, 0, vertSize / 3);
        break;
    case 4:
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s glDrawArrays三角形绘制.", __func__);
        glDrawArrays(GL_TRIANGLES, 0, vertSize / 3);
        break;
    case 5:
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s glDrawArrays三角形带绘制.", __func__);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertSize / 3);
        break;
    case 6:
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s glDrawArrays三角形扇形绘制.",
                     __func__);
        glDrawArrays(GL_TRIANGLE_FAN, 0, vertSize / 3);
        break;
    default:
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "%{public}s glDrawArrays显示为点.", __func__);
        glDrawArrays(GL_POINTS, 0, vertSize / 3);
        break;
    }
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glDrawArrays error.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    glDisableVertexAttribArray(0);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "%{public}s,glDisableVertexAttribArray error.errcode:%{public}d", __func__, eglGetError());
        return false;
    }
    return true;
}

GLuint EGLCore::PrepareDraw() {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "PrepareDraw start.");
    if ((eglDisplay_ == nullptr) || (eglSurface_ == nullptr) || (eglContext_ == nullptr) ||
        (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "PrepareDraw: param error.errcode:%{public}d",
                     eglGetError());
        return POSITION_ERROR;
    }
    glViewport(DEFAULT_X_POSITION, DEFAULT_Y_POSITION, width_, height_);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "PrepareDraw glViewport error.errcode:%{public}d",
                     eglGetError());
        return POSITION_ERROR;
    }
    glClearColor(GL_RED_DEFAULT, GL_GREEN_DEFAULT, GL_BLUE_DEFAULT, GL_ALPHA_DEFAULT);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "PrepareDraw glClearColor error.errcode:%{public}d", eglGetError());
        return POSITION_ERROR;
    }
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(program_);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "PrepareDraw glUseProgram error.errcode:%{public}d", eglGetError());
        return POSITION_ERROR;
    }

    // 检查程序连接状态
    GLint linkStatus;
    glGetProgramiv(program_, GL_LINK_STATUS, &linkStatus);
    glGetAttribLocation(program_, POSITION_NAME);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "PrepareDraw glGetAttribLocation error.errcode:%{public}d", eglGetError());
        return POSITION_ERROR;
    }

    return 0;
}

bool EGLCore::ExecuteDraw(GLint position, const GLfloat *color, const GLfloat shapeVertices[], unsigned long vertSize) {
    if ((position > 0) || (color == nullptr) || (vertSize / sizeof(shapeVertices[0])) != SHAPE_VERTICES_SIZE) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ExecuteDraw: param error.errcode:%d",
                     eglGetError());
        return false;
    }
    // The gl function has no return value.
    glVertexAttribPointer(position, POINTER_SIZE, GL_FLOAT, GL_FALSE, 0, shapeVertices);
    glEnableVertexAttribArray(position);
    glVertexAttrib4fv(1, color);
    glDrawArrays(GL_TRIANGLE_FAN, 0, TRIANGLE_FAN_SIZE);
    glDisableVertexAttribArray(position);

    return true;
}

void EGLCore::Draw(int &hasDraw) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "Draw start.");
    flag_ = false;
    if ((eglDisplay_ == nullptr) || (eglSurface_ == nullptr) || (eglContext_ == nullptr) ||
        (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw: param error.errcode:%{public}d",
                     eglGetError());
        return;
    }
    glViewport(DEFAULT_X_POSITION, DEFAULT_Y_POSITION, width_, height_);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw glViewport error.errcode:%{public}d",
                     eglGetError());
        return;
    }
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore",
                 "Draw glViewport success.x:%{public}d,y:%{public}d,with:%{public}d,height:%{public}d.",
                 DEFAULT_X_POSITION, DEFAULT_Y_POSITION, width_, height_);
    glClearColor(GL_RED_DEFAULT, GL_GREEN_DEFAULT, GL_BLUE_DEFAULT, GL_ALPHA_DEFAULT);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw glClearColor error.errcode:%{public}d",
                     eglGetError());
        return;
    }
    glClear(GL_COLOR_BUFFER_BIT);
    GLint position = glGetAttribLocation(program_, POSITION_NAME);
    if (glGetError() != GL_NO_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "Draw glGetAttribLocation error.errcode:%{public}d", eglGetError());
        return;
    }

    if (!ExecuteDraw(position, BACKGROUND_COLOR, BACKGROUND_RECTANGLE_VERTICES,
                     sizeof(BACKGROUND_RECTANGLE_VERTICES))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw background failed");
        return;
    }

    // Divided into five quadrilaterals and calculate one of the quadrilateral's Vertices
    GLfloat rotateX = 0;
    GLfloat rotateY = FIFTY_PERCENT * height_;
    GLfloat centerX = 0;
    // Convert DEG(54° & 18°) to RAD
    GLfloat centerY = -rotateY * (M_PI / 180 * 54) * (M_PI / 180 * 18);
    // Convert DEG(18°) to RAD
    GLfloat leftX = -rotateY * (M_PI / 180 * 18);
    GLfloat leftY = 0;
    // Convert DEG(18°) to RAD
    GLfloat rightX = rotateY * (M_PI / 180 * 18);
    GLfloat rightY = 0;

    const GLfloat shapeVertices[] = {centerX / width_, centerY / height_, leftX / width_,  leftY / height_,
                                     rotateX / width_, rotateY / height_, rightX / width_, rightY / height_};

    if (!ExecuteDrawStar(position, DRAW_COLOR, shapeVertices, sizeof(shapeVertices))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw shape failed");
        return;
    }

    // Convert DEG(72°) to RAD
    GLfloat rad = M_PI / 180 * 72;
    // Rotate four times
    for (int i = 0; i < NUM_4; ++i) {
        Rotate2d(centerX, centerY, &rotateX, &rotateY, rad);
        Rotate2d(centerX, centerY, &leftX, &leftY, rad);
        Rotate2d(centerX, centerY, &rightX, &rightY, rad);

        const GLfloat shapeVertices[] = {centerX / width_, centerY / height_, leftX / width_,  leftY / height_,
                                         rotateX / width_, rotateY / height_, rightX / width_, rightY / height_};

        if (!ExecuteDrawStar(position, DRAW_COLOR, shapeVertices, sizeof(shapeVertices))) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw shape failed");
            return;
        }
    }

    if (!FinishDraw()) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw FinishDraw failed");
        return;
    }
    hasDraw = 1;

    flag_ = true;
}
void EGLCore::Background() {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "Background start.");
    GLint position = PrepareDraw();
    if (position == POSITION_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Background get position failed");
        return;
    }

    if (!ExecuteDraw(position, BACKGROUND_COLOR, BACKGROUND_RECTANGLE_VERTICES,
                     sizeof(BACKGROUND_RECTANGLE_VERTICES))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Background execute draw failed");
        return;
    }

    if (!FinishDraw()) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Background FinishDraw failed");
        return;
    }
}

void EGLCore::UpdateSize(int width, int height) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "UpdateSize start.width:%{public}d,height%{public}d.",
                 width, height);
    width_ = width;
    height_ = height;
    if (width_ > 0) {
        widthPercent_ = FIFTY_PERCENT * height_ / width_;
    }
}


void EGLCore::Release() {
    if ((eglDisplay_ == nullptr) || (eglSurface_ == nullptr) || (!eglDestroySurface(eglDisplay_, eglSurface_))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglDestroySurface failed");
    }

    if ((eglDisplay_ == nullptr) || (eglContext_ == nullptr) || (!eglDestroyContext(eglDisplay_, eglContext_))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglDestroyContext failed");
    }

    if ((eglDisplay_ == nullptr) || (!eglTerminate(eglDisplay_))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglTerminate failed");
    }
}

bool EGLCore::ExecuteDrawStar(GLint position, const GLfloat *color, const GLfloat shapeVertices[],
                              unsigned long vertSize) {
    if ((position > 0) || (color == nullptr) || (vertSize / sizeof(shapeVertices[0])) != SHAPE_VERTICES_SIZE) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ExecuteDraw: param error");
        return false;
    }

    glVertexAttribPointer(position, POINTER_SIZE, GL_FLOAT, GL_FALSE, 0, shapeVertices);
    glVertexAttribPointer(1, POINTER_SIZE, GL_FLOAT, GL_FALSE, 0, color);
    glEnableVertexAttribArray(position);
    glEnableVertexAttribArray(1);
    glVertexAttrib4fv(1, color);
    glDrawArrays(GL_TRIANGLE_FAN, 0, TRIANGLE_FAN_SIZE);
    glDisableVertexAttribArray(position);
    glDisableVertexAttribArray(1);

    return true;
}

bool EGLCore::ExecuteDrawNewStar(GLint position, const GLfloat *color, const GLfloat shapeVertices[],
                                 unsigned long vertSize) {
    if ((position > 0) || (color == nullptr) || (vertSize / sizeof(shapeVertices[0])) != SHAPE_VERTICES_SIZE) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ExecuteDraw: param error");
        return false;
    }

    // The gl function has no return value.
    glVertexAttribPointer(position, POINTER_SIZE, GL_FLOAT, GL_FALSE, 0, shapeVertices);
    glEnableVertexAttribArray(position);
    glVertexAttrib4fv(1, color);
    glDrawArrays(GL_TRIANGLE_FAN, 0, TRIANGLE_FAN_SIZE);
    glDisableVertexAttribArray(position);

    return true;
}

void EGLCore::Rotate2d(GLfloat centerX, GLfloat centerY, GLfloat *rotateX, GLfloat *rotateY, GLfloat theta) {
    GLfloat tempX = cos(theta) * (*rotateX - centerX) - sin(theta) * (*rotateY - centerY);
    GLfloat tempY = sin(theta) * (*rotateX - centerX) + cos(theta) * (*rotateY - centerY);
    *rotateX = tempX + centerX;
    *rotateY = tempY + centerY;
}

bool EGLCore::FinishDraw() {
    // The gl function has no return value.
    glFlush();
    glFinish();
    return eglSwapBuffers(eglDisplay_, eglSurface_);
}

void EGLCore::ChangeColor(int &hasChangeColor) {
    if (!flag_) {
        return;
    }
    GLint position = PrepareDraw();
    if (position == POSITION_ERROR) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ChangeColor get position failed.errcode:%d",
                     eglGetError());
        return;
    }

    if (!ExecuteDraw(position, BACKGROUND_COLOR, BACKGROUND_RECTANGLE_VERTICES,
                     sizeof(BACKGROUND_RECTANGLE_VERTICES))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "ChangeColor execute draw background failed.errcode:%d", eglGetError());
        return;
    }
    // Divided into five quadrilaterals and calculate one of the quadrilateral's Vertices
    GLfloat rotateX = 0;
    GLfloat rotateY = FIFTY_PERCENT * height_;
    GLfloat centerX = 0;
    // Convert DEG(54° & 18°) to RAD
    GLfloat centerY = -rotateY * (M_PI / 180 * 54) * (M_PI / 180 * 18);
    // Convert DEG(18°) to RAD
    GLfloat leftX = -rotateY * (M_PI / 180 * 18);
    GLfloat leftY = 0;
    // Convert DEG(18°) to RAD
    GLfloat rightX = rotateY * (M_PI / 180 * 18);
    GLfloat rightY = 0;

    const GLfloat shapeVertices[] = {centerX / width_, centerY / height_, leftX / width_,  leftY / height_,
                                     rotateX / width_, rotateY / height_, rightX / width_, rightY / height_};

    if (!ExecuteDrawNewStar(0, CHANGE_COLOR, shapeVertices, sizeof(shapeVertices))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw shape failed");
        return;
    }

    // Convert DEG(72°) to RAD
    GLfloat rad = M_PI / 180 * 72;
    // Rotate four times
    for (int i = 0; i < NUM_4; ++i) {
        Rotate2d(centerX, centerY, &rotateX, &rotateY, rad);
        Rotate2d(centerX, centerY, &leftX, &leftY, rad);
        Rotate2d(centerX, centerY, &rightX, &rightY, rad);
        const GLfloat shapeVertices[] = {centerX / width_, centerY / height_, leftX / width_,  leftY / height_,
                                         rotateX / width_, rotateY / height_, rightX / width_, rightY / height_};

        if (!ExecuteDrawNewStar(position, CHANGE_COLOR, shapeVertices, sizeof(shapeVertices))) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw shape failed");
            return;
        }
    }

    if (!FinishDraw()) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ChangeColor FinishDraw failed");
    }
    hasChangeColor = 1;
}

/**
 * 加载着色器
 * @param type  GL_VERTEX_SHADER-定点着色器   GL_FRAGMENT_SHADER-片段说着色器
 * @param shaderSrc 着色器代码
 * @return
 */
GLuint EGLCore::LoaderShader(GLenum type, const char *shaderSrc) {
    if ((type <= 0) || (shaderSrc == nullptr)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "LoaderShader加载着色器失败，参数异常。");
        return PROGRAM_ERROR;
    }

    GLuint shader = glCreateShader(type);
    if (shader == 0) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "glCreateShader fail。");
        return PROGRAM_ERROR;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "EGLCore", "glCreateShader着色器ID：%{public}d。", shader);

    glShaderSource(shader, 1, &shaderSrc, nullptr);
    glCompileShader(shader);

    GLint compiled;
    // 检查着色器编译结果
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
    if (compiled != 0) {
        // 此时表示着色器编译成功
        return shader;
    } else {
        // 此时表示着色器编译失败
        GLint logLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
        char *log = new char[logLength];
        glGetShaderInfoLog(shader, logLength, nullptr, log);
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore",
                     "glCompileShader failed，msg:%{public}s.code：%{public}d。", log, glGetError());
        delete[] log;
        glDeleteShader(shader);
        return PROGRAM_ERROR;
    }
}